// -*- C++ -*-

#include "Service_Type_Impl.h"

void* Service_Type_Impl::object(void) const
{
	return this->obj_;
}

const char* Service_Type_Impl::name(void) const
{
	return this->name_;
}

void Service_Type_Impl::name(const char * n)
{
	Tool::strdelete( const_cast<char*> (this->name_) );
	this->name_ = Tool::strnew( n );
}

void Service_Type_Impl::dump(void) const
{

}

Service_Type_Impl::Service_Type_Impl(void *object,
									 const char *s_name,
									 u_int flags,
									 Service_Object_Exterminator gobbler )
									 :name_(0),
									 obj_(object),
									 gobbler_(gobbler),
									 flags_(flags)
{
	this->name(s_name);
}

Service_Type_Impl::~Service_Type_Impl(void)
{
	// It's ok to call this, even though we may have already deleted it
	// in the fini() method since it would then be NULL.
	delete []const_cast<char*>(this->name_);
}

int Service_Type_Impl::fini(void) const
{
	if ( Tool::debug() )
	{
		ACE_DEBUG((LM_DEBUG,
			ACE_LIB_TEXT("destroying %s, flags = %d\n"),
			this->name_,
			this->flags_));
	}

	delete []const_cast<char*>(this->name_);
	(const_cast<Service_Type_Impl*>(this))->name_ = 0;

	if ( BIT_ENABLED( this->flags_,
					Service_Type::DELETE_OBJ) )
	{
		if ( gobbler_ != 0 )
		{
			gobbler_( this->object() );
		}
		else
			// Cast to remove const-ness.
			operator delete ((void*)this->object());
	}

	if ( BIT_ENABLED( this->flags_,
					Service_Type::DELETE_THIS) )
	{
		delete const_cast<Service_Type_Impl*> (this);
	}
	return 0;
}


//////////////////////////////////////////////////////////////////////////
Service_Object_Type::Service_Object_Type(void *so,
										 const char *name,
										 u_int flags ,
										 Service_Object_Exterminator gobbler)
										 :Service_Type_Impl(so, name, flags, gobbler)
{

}

int Service_Object_Type::init(int argc, char* argv[] ) const
{
	void* const obj = this->object();

	Service_Object* const so = static_cast<Service_Object*>(obj);
	if ( so == 0 )
		return -1;
	else
		return so->init(argc, argv);
}

int Service_Object_Type::fini(void) const
{
	void* const obj = this->object();

	Service_Object* const so = static_cast<Service_Object*>(obj);
	if ( so )
	{
		so->fini();
	}
	return Service_Type_Impl::fini();
}

int Service_Object_Type::suspend (void) const
{
	return static_cast<Service_Object *> (this->object ())->suspend ();
}

int Service_Object_Type::resume (void) const
{
	return static_cast<Service_Object *> (this->object ())->resume ();
}

int Service_Object_Type::info (char **str, size_t len) const
{
	return static_cast<Service_Object *> (this->object ())->info (str, len);
}